# -*- coding: utf-8 -*-
# @Time    : 2019/10/3 17:02
# @Author  : LiHaowen
# @Email   : lihaowen2017@163.com
# @File    : study_consumers.py

# event loop/event handler/sync/async
# 同步consumer
from channels.consumer import SyncConsumer
from channels.consumer import AsyncConsumer


# 同步consumer
class EchoConsumer(SyncConsumer):
    def websocket_connect(self, event):
        self.send({
            # 接受websocket信息, type为固定写法属于ASGI接口规范
            "type": "websocket.accept"
        })

    def websocket_recieve(self, event):
        user = self.scope["user"]
        path = self.scope["path"]  # Request请求的路径，HTTP，WebSocket
        # self.scope["headers"]
        # self.scope["method"]  # http
        self.send({
            "type": "websocket.send",
            "text": event["text"]
        })


class EchoAsyncConsumer(AsyncConsumer):
    # 异步consumer
    async def websocket_connect(self, event):
        # 同步逻辑
        # import requests
        # requests.get("url")
        # 改成异步逻辑
        # import aiohttp
        await self.send({
            # 接受websocket信息, type为固定写法属于ASGI接口规范
            "type": "websocket.accept"
        })

    async def websocket_recieve(self, event):
        # ORM 同步代码
        # user = User.objects.get(username=username)
        # ORM 同步变异步 方式一
        # from channels.db import database_sync_to_async
        # user = await database_sync_to_async(User.objects.get(username=username))
        # ORM 同步变异步 方式二
        # @database_sync_to_async
        # def get_username(username):
        #     return User.objects.get(username=username)

        await self.send({
            "type": "websocket.send",
            "text": event["text"]
        })


# 什么时候使用sync什么时候使用async
# 异步代码中一定要写异步逻辑，如果写同步逻辑则无法起到异步并发作用

# scope，在ASGI接口规范中定义了类似于.request


from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer


class MyConsumer(WebsocketConsumer):
    """同步，同步中需要写异步代码则需要调用异步方法进行修改"""
    def connect(self):
        self.accept()  # 不传参表示接受websocket连接
        self.accept(subprotocol="you protocol")  # 自定义子协议，子协议怎么写？
        self.close(code=403)  # 拒绝连接;code传递给前端的状态码

    def receive(self, text_data=None, bytes_data=None):
        """接受数据"""
        self.send(text_data="aaa")  # 传递文本文件
        self.send(bytes_data="aaa")  # 把字符串转换成二进制的帧返回
        self.close()  # 断开连接

    def disconnect(self, code):
        """想关闭websocket时直接调用"""
        pass


class MyAsyncConsumer(WebsocketConsumer):
    """异步"""
    async def connect(self):
        await self.accept()  # 不传参表示接受websocket连接
        await self.accept(subprotocol="you protocol")  # 自定义子协议，子协议怎么写？
        await self.close(code=403)  # 拒绝连接;code传递给前端的状态码

    async def receive(self, text_data=None, bytes_data=None):
        """接受数据"""
        await self.send(text_data="aaa")  # 传递文本文件
        await self.send(bytes_data="aaa")  # 把字符串转换成二进制的帧返回
        await self.close()  # 断开连接

    async def disconnect(self, code):
        """想关闭websocket时直接调用"""
        pass
